
/*
    客户端流程
        1、创建套接字端口 
        2、为套接字绑定地址信息 不推荐主动绑定地址，降低端口冲突的几率，保证数据发送的安全性
        3、向服务端发起连接请求
        4、收发数据  为服务端特定套接字服务
        5、关闭套接字  释放资源
    
    客户端接口
        创建套接字 int socket(int domain, int type, int protocol)
            domain 地址域 本地通信 AF_LOCAL, ipv4 AF_INET, ipv6 AD_INET6
            type 套接字类型 流式套接字 SOCK_STREAM, 数据报套接字 SOCK_DGRAM
            protocol 协议类型  tcp IPPROTO_TCP, UDP IPPROTO_UDP  
            失败返回-1，成功返回文件描述符-非负整数，套接字所有其他接口的操作句柄
        
        向服务端发起连接请求 int connect(int sockfd, struct sockaddr * srv_addr, int len)
            sockfd 向哪个服务器发送连接请求
            srv_addr 服务端地址信息

        接收数据，接收发送者地址便于回复 ssize_t recv(int sockfd, char *buf, int len, int flag)
            sockfd 创建套接字返回的操作句柄
            buf 缓冲区，用于接收从接收缓冲区中取出的数据
            len 要接收的数据长度
            flag 操作选项标志，默认为0，表示阻塞操作
            成功返回实际接收到的数据字节长度，失败返回-1
        
        发送数据 ssize_t send(int sockfd, char *data, int len, int flag)
            sockfd 创建套接字返回的操作句柄
            data 要发送的数据地址
            len 要发送数据长度
            flag 默认为0，阻塞操作
            成功返回实际发送的数据字节长度，失败返回-1
        
        关闭套接字 int close(int sockfd)
*/

#include <iostream>
#include <string>
#include "tcpSocket.h"

int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		std::cout << "Usage: ./tcp_cli ip port" << std::endl;
		return -1;
	}
	std::string srv_ip = argv[1];
	uint16_t srv_port = std::stoi(argv[2]);

	TcpSocket sock;
	sock.Socket();
	sock.Connect(srv_ip, srv_port);
	while (1)
	{
        std::string outputBuf, inputBuf;
		sock.Recv(&outputBuf, 1);
		std::cin >> inputBuf;
		if(inputBuf != "")
		{
			std::cout << "client say:" << inputBuf << std::endl;
            sock.Send(inputBuf);
            inputBuf.clear();
		}
		if(outputBuf != "")
		{
			std::cout << "server say:" << outputBuf;
			outputBuf.clear();
		}
		std::cout << "outputBuf=" << outputBuf << std::endl;
		std::cout << "inputBuf=" << inputBuf << std::endl;
	}
	sock.Close();
	return 0;
}


